package com.lemobar.pay.service.impl.alipay;

import com.google.gson.FieldNamingPolicy;
import com.google.gson.GsonBuilder;
import com.lemobar.pay.config.AliPayConfig;
import com.lemobar.pay.config.SignType;
import com.lemobar.pay.constants.AliPayConstants;
import com.lemobar.pay.enums.AliPayTradeStatusEnum;
import com.lemobar.pay.enums.LmbPayExResultEnum;
import com.lemobar.pay.enums.LmbPayTypeEnum;
import com.lemobar.pay.exception.LmbPayException;
import com.lemobar.pay.model.*;
import com.lemobar.pay.model.alipay.AliPayApi;
import com.lemobar.pay.model.alipay.request.*;
import com.lemobar.pay.model.alipay.response.*;
import com.lemobar.pay.service.impl.LmbPayServiceImpl;
import com.lemobar.pay.utils.*;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;


/**
 * 支付宝支付 统一分发服务
 */
@Slf4j
public class AliPayServiceImpl extends LmbPayServiceImpl {

    protected final static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    protected AliPayConfig aliPayConfig;

    @Override
    public void setAliPayConfig(AliPayConfig aliPayConfig) {
        this.aliPayConfig = aliPayConfig;
    }

    private Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(AliPayConstants.ALIPAY_GATEWAY_OPEN)
            .addConverterFactory(GsonConverterFactory.create(
                    //下划线驼峰互转
                    new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create()
            ))
            .client(new OkHttpClient.Builder()
                    .addInterceptor((new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)))
                    .build()
            )
            .build();

    private Retrofit devRetrofit = new Retrofit.Builder()
            .baseUrl(AliPayConstants.ALIPAY_GATEWAY_OPEN_DEV)
            .addConverterFactory(GsonConverterFactory.create(
                    new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create()  //下划线驼峰互转
            ))
            .client(new OkHttpClient.Builder()
                    .addInterceptor((new HttpLoggingInterceptor()
                            .setLevel(HttpLoggingInterceptor.Level.BODY)))
                    .build()
            ).build();

    @Override
    public PayResponse pay(PayRequest request) {
        if (request.getPayTypeEnum() == LmbPayTypeEnum.ALIPAY_H5) {     // 统一的
            AlipayH5ServiceImpl alipayH5Service = new AlipayH5ServiceImpl();
            alipayH5Service.setAliPayConfig(aliPayConfig);
            return alipayH5Service.pay(request);
        } else if (request.getPayTypeEnum() == LmbPayTypeEnum.ALIPAY_WAP) { // WAP
            AlipayWapServiceImpl alipayWapService = new AlipayWapServiceImpl();
            alipayWapService.setAliPayConfig(aliPayConfig);
            return alipayWapService.pay(request);
        } else if (request.getPayTypeEnum() == LmbPayTypeEnum.ALIPAY_APP) { // APP
            AlipayAppServiceImpl appService = new AlipayAppServiceImpl();
            appService.setAliPayConfig(aliPayConfig);
            return appService.pay(request);
        } else if (request.getPayTypeEnum() == LmbPayTypeEnum.ALIPAY_PC) {
            //TODO
            return null;
        }  else if (request.getPayTypeEnum() == LmbPayTypeEnum.ALIPAY_QRCODE) {
            //TODO
            AlipayQRCodeServiceImpl alipayQRCodeService = new AlipayQRCodeServiceImpl();
            alipayQRCodeService.setAliPayConfig(aliPayConfig);
            return alipayQRCodeService.pay(request);
        } else if (request.getPayTypeEnum() == LmbPayTypeEnum.ALIPAY_BARCODE) {     // 面对面-付款码
            AlipayBarCodeServiceImpl alipayBarCodeService = new AlipayBarCodeServiceImpl();
            alipayBarCodeService.setAliPayConfig(aliPayConfig);
            return alipayBarCodeService.pay(request);
        }
        return null;


        /*

        Map<String, String> requestParams = new HashMap<>();
        requestParams.put("out_trade_no", request.getOrderId());
        AliPayPcRequest aliPayRequest = new AliPayPcRequest();
        if (request.getPayTypeEnum() == LmbPayTypeEnum.ALIPAY_PC) {
            requestParams.put("product_code", AliPayConstants.FAST_INSTANT_TRADE_PAY);
            aliPayRequest.setMethod(AliPayConstants.ALIPAY_TRADE_PAGE_PAY);
        } else {
            requestParams.put("product_code", AliPayConstants.QUICK_WAP_PAY);
            aliPayRequest.setMethod(AliPayConstants.ALIPAY_TRADE_WAP_PAY);
        }
        requestParams.put("total_amount", String.valueOf(request.getOrderAmount()));
        requestParams.put("subject", String.valueOf(request.getOrderName()));

        aliPayRequest.setAppId(aliPayConfig.getAppId());
        aliPayRequest.setCharset("utf-8");
        aliPayRequest.setSignType(AliPayConstants.SIGN_TYPE_RSA2);
        aliPayRequest.setNotifyUrl(aliPayConfig.getNotifyUrl());
        //优先使用PayRequest.returnUrl
        aliPayRequest.setReturnUrl(StringUtils.isEmpty(request.getReturnUrl()) ? aliPayConfig.getReturnUrl() : request.getReturnUrl());
        aliPayRequest.setTimestamp(LocalDateTime.now().format(formatter));
        aliPayRequest.setVersion("1.0");
        // 剔除空格、制表符、换行
        aliPayRequest.setBizContent(JsonUtil.toJson(requestParams).replaceAll("\\s*", ""));
        aliPayRequest.setSign(AliPaySignature.sign(MapUtil.object2MapWithUnderline(aliPayRequest), aliPayConfig.getPrivateKey()));

        Map<String, String> parameters = MapUtil.object2MapWithUnderline(aliPayRequest);
        Map<String, String> applicationParams = new HashMap<>();
        applicationParams.put("biz_content", aliPayRequest.getBizContent());
        parameters.remove("biz_content");
        String baseUrl = WebUtil.getRequestUrl(parameters, aliPayConfig.isSandbox());
        String body = WebUtil.buildForm(baseUrl, applicationParams);

        // pc 网站支付 只需返回body
        PayResponse response = new PayResponse();
        response.setBody(body);
        return response;
         */

    }


    @Override
    public QueryResponse query(QueryRequest request) {
        AliPayTradeQueryRequest aliPayTradeQueryRequest = new AliPayTradeQueryRequest();
        aliPayTradeQueryRequest.setAppId(aliPayConfig.getAppId());
        aliPayTradeQueryRequest.setTimestamp(LocalDateTime.now().format(formatter));
        AliPayTradeQueryRequest.BizContent bizContent = new AliPayTradeQueryRequest.BizContent();
        bizContent.setOutTradeNo(request.getOrderId());
        bizContent.setTradeNo(request.getOutOrderId());
        aliPayTradeQueryRequest.setBizContent(JsonUtil.toJsonWithUnderscores(bizContent).replaceAll("\\s*", ""));
        aliPayTradeQueryRequest.setSign(AliPaySignature.sign(MapUtil.object2MapWithUnderline(aliPayTradeQueryRequest), aliPayConfig.getPrivateKey()));

        Call<AliPayTradeQueryResponse> call = null;
        if (aliPayConfig.isSandbox()) {
            call = devRetrofit.create(AliPayApi.class).tradeQuery((MapUtil.object2MapWithUnderline(aliPayTradeQueryRequest)));
        } else {
            call = retrofit.create(AliPayApi.class).tradeQuery((MapUtil.object2MapWithUnderline(aliPayTradeQueryRequest)));
        }
        Response<AliPayTradeQueryResponse> retrofitResponse = null;
        try {
            retrofitResponse = call.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        assert retrofitResponse != null;
        if (!retrofitResponse.isSuccessful()) {
            throw new RuntimeException("【查询支付宝订单】 alipay.trade.query. 网络异常");
        }
        assert retrofitResponse.body() != null;
        AliPayTradeQueryResponse.Content response = retrofitResponse.body().getAlipayTradeQueryResponse();
        /*
        if (!response.getCode().equals(AliPayConstants.RESPONSE_CODE_SUCCESS)) {
            throw new RuntimeException("【查询支付宝订单】 alipay.trade.query. code=" + response.getCode() + ", returnMsg=" + response.getMsg() + String.format("|%s|%s", response.getSubCode(), response.getSubMsg()));
        }
         */

        return QueryResponse.builder()
                .resultCode(response.getCode())
                .errCode(response.getSubCode())
                .errCodeDes(response.getSubMsg())
                .orderId(response.getOutTradeNo())
                .outOrderId(response.getTradeNo())
                .openid(response.getBuyerUserId())
                .orderStatus(response.getTradeStatus())
                .orderAmount(response.getTotalAmount())
                .finishTime(response.getSendPayDate())
                .build();
    }

    @Override
    public CloseResponse close(CloseRequest request) {
        AliPayTradeCloseRequest aliPayTradeCloseRequest = new AliPayTradeCloseRequest();
        aliPayTradeCloseRequest.setAppId(aliPayConfig.getAppId());
        aliPayTradeCloseRequest.setTimestamp(LocalDateTime.now().format(formatter));
        AliPayTradeQueryRequest.BizContent bizContent = new AliPayTradeQueryRequest.BizContent();
        bizContent.setOutTradeNo(request.getOrderId());
        bizContent.setTradeNo(request.getOutOrderId());
        aliPayTradeCloseRequest.setBizContent(JsonUtil.toJsonWithUnderscores(bizContent).replaceAll("\\s*", ""));
        aliPayTradeCloseRequest.setSign(AliPaySignature.sign(MapUtil.object2MapWithUnderline(aliPayTradeCloseRequest), aliPayConfig.getPrivateKey()));

        Call<AlipayTradeCloseResponse> call = null;
        if (aliPayConfig.isSandbox()) {
            call = devRetrofit.create(AliPayApi.class).close((MapUtil.object2MapWithUnderline(aliPayTradeCloseRequest)));
        } else {
            call = retrofit.create(AliPayApi.class).close((MapUtil.object2MapWithUnderline(aliPayTradeCloseRequest)));
        }

        Response<AlipayTradeCloseResponse> retrofitResponse = null;
        try {
            retrofitResponse = call.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        assert retrofitResponse != null;
        if (!retrofitResponse.isSuccessful()) {
            throw new RuntimeException("【关闭支付宝订单】alipay.trade.close.网络异常");
        }
        assert retrofitResponse.body() != null;
        AlipayTradeCloseResponse.Content response = retrofitResponse.body().getAlipayTradeCloseResponse();

        /*
        if (!response.getCode().equals(AliPayConstants.RESPONSE_CODE_SUCCESS)) {
            throw new RuntimeException("【关闭支付宝订单】alipay.trade.close.code=" + response.getCode() + ", returnMsg=" + response.getMsg() + String.format("|%s|%s", response.getSubCode(), response.getSubMsg()));
        }
         */

        return CloseResponse.builder()
                .resultCode(response.getCode())
                .errCode(response.getSubCode())
                .errCodeDes(response.getSubMsg())
                .build();
    }


    /**
     * 通过商户网站唯一订单号 out_trade_no 或支付宝交易号 trade_no，将对应订单支付款退还给买家，
     * 支付宝将在收到退款请求并且验证成功之后，按照退款规则将支付款按原路退到买家帐号上。支持全额或部分退款。
     * (如果系统异常,重新发起退款请求,确保out_request_no保持一致)
     * (开发者也可以在商家中心(b.alipay.com)中退款。)
     * (退款接口会根据外部请求号 out_request_no 幂等返回，因此同一笔交易需要多次部分退款时，必须使用不同的 out_request_no)
     *
     * 手机网站WAP支付 https://opendocs.alipay.com/open/203/105285#%E9%80%80%E6%AC%BE
     * APP支付 https://opendocs.alipay.com/open/204/01dcc0#%E9%80%80%E6%AC%BE
     * 付款码支付 https://opendocs.alipay.com/open/194/106039#%E9%80%80%E6%AC%BE
     */
    @Override
    public RefundResponse refund(RefundRequest request) {
        AliPayTradeRefundRequest aliPayTradeRefundRequest = new AliPayTradeRefundRequest();
        aliPayTradeRefundRequest.setAppId(aliPayConfig.getAppId());
        aliPayTradeRefundRequest.setTimestamp(LocalDateTime.now().format(formatter));
        AliPayTradeRefundRequest.BizContent bizContent = new AliPayTradeRefundRequest.BizContent();
        bizContent.setOutTradeNo(request.getOrderId());
        bizContent.setTradeNo(request.getOutOrderId());
        bizContent.setRefundAmount(request.getRefundAmount());
        bizContent.setRefundReason(request.getRefundReason());
        bizContent.setOutRequestNo(request.getRefundId());
        aliPayTradeRefundRequest.setBizContent(JsonUtil.toJsonWithUnderscores(bizContent).replaceAll("\\s*", ""));
        aliPayTradeRefundRequest.setSign(AliPaySignature.sign(MapUtil.object2MapWithUnderline(aliPayTradeRefundRequest), aliPayConfig.getPrivateKey()));
        Call<AliPayTradeRefundResponse> call = null;
        if (aliPayConfig.isSandbox()) {
            call = devRetrofit.create(AliPayApi.class).refund((MapUtil.object2MapWithUnderline(aliPayTradeRefundRequest)));
        } else {
            call = retrofit.create(AliPayApi.class).refund((MapUtil.object2MapWithUnderline(aliPayTradeRefundRequest)));
        }

        Response<AliPayTradeRefundResponse> retrofitResponse = null;
        try {
            retrofitResponse = call.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        assert retrofitResponse != null;
        if (!retrofitResponse.isSuccessful()) {
            throw new RuntimeException("【支付宝退款】alipay.trade.refund.网络异常");
        }
        assert retrofitResponse.body() != null;
        AliPayTradeRefundResponse.Content response = retrofitResponse.body().getAlipayTradeRefundResponse();
        /*
        if (!response.getCode().equals(AliPayConstants.RESPONSE_CODE_SUCCESS)) {
            throw new RuntimeException("【支付宝退款】alipay.trade.refund.code=" + response.getCode() + ", returnMsg=" + response.getMsg() + String.format("|%s|%s", response.getSubCode(), response.getSubMsg()));
        }
         */

        return RefundResponse.builder()
                .resultCode(response.getCode())
                .errCode(response.getSubCode())
                .errCodeDes(response.getSubMsg())
                .outOrderId(response.getTradeNo())
                .orderId(response.getOutTradeNo())
                .outRefundId("") // 外部退款单号。支付宝 没有
                .refundId(request.getRefundId())    // 退款请求号。支付宝没响应,用传入时指定的商户退款单号
                .refundAmount(response.getRefundFee())
                .build();
    }

    @Override
    public RefundQueryResponse refundQuery(RefundQueryRequest request) {
        AlipayTradeFastpayRefundQueryRequest alipayTradeFastpayRefundQueryRequest = new AlipayTradeFastpayRefundQueryRequest();
        alipayTradeFastpayRefundQueryRequest.setAppId(aliPayConfig.getAppId());
        alipayTradeFastpayRefundQueryRequest.setTimestamp(LocalDateTime.now().format(formatter));
        AlipayTradeFastpayRefundQueryRequest.BizContent bizContent = new AlipayTradeFastpayRefundQueryRequest.BizContent();
        bizContent.setOutTradeNo(request.getOrderId());
        bizContent.setTradeNo(request.getOutOrderId());
        bizContent.setOutRequestNo(request.getRefundId());
        alipayTradeFastpayRefundQueryRequest.setBizContent(JsonUtil.toJsonWithUnderscores(bizContent).replaceAll("\\s*", ""));
        alipayTradeFastpayRefundQueryRequest.setSign(AliPaySignature.sign(MapUtil.object2MapWithUnderline(alipayTradeFastpayRefundQueryRequest), aliPayConfig.getPrivateKey()));

        Call<AlipayTradeFastpayRefundQueryResponse> call = null;
        if (aliPayConfig.isSandbox()) {
            call = devRetrofit.create(AliPayApi.class).refundQuery((MapUtil.object2MapWithUnderline(alipayTradeFastpayRefundQueryRequest)));
        } else {
            call = retrofit.create(AliPayApi.class).refundQuery((MapUtil.object2MapWithUnderline(alipayTradeFastpayRefundQueryRequest)));
        }
        Response<AlipayTradeFastpayRefundQueryResponse> retrofitResponse = null;
        try {
            retrofitResponse = call.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        assert retrofitResponse != null;
        if (!retrofitResponse.isSuccessful()) {
            throw new RuntimeException("【查询支付宝订单退款】alipay.trade.fastpay.refund.query.网络异常");
        }
        assert retrofitResponse.body() != null;
        AlipayTradeFastpayRefundQueryResponse.Content response = retrofitResponse.body().getAlipayTradeFastpayRefundQueryResponse();
        /*
        if (!response.getCode().equals(AliPayConstants.RESPONSE_CODE_SUCCESS)) {
            throw new RuntimeException("【查询支付宝订单退款】alipay.trade.fastpay.refund.query.code=" + response.getCode() + ", returnMsg=" + response.getMsg() + String.format("|%s|%s", response.getSubCode(), response.getSubMsg()));
        }
         */

        return RefundQueryResponse.builder()
                .resultCode(response.getCode())
                .errCode(response.getSubCode())
                .errCodeDes(response.getSubMsg())
                .orderId(response.getOutTradeNo())
                .outOrderId(response.getTradeNo())
                .orderAmount(response.getTotalAmount())
                .refundId(response.getOutRequestNo())
                .refundAmount(response.getRefundAmount())
                .refundStatus(response.getRefundStatus())
                .refundFinishTime(response.getGmtRefundPay())
                .build();
    }


    @Override
    public ReverseResponse reverse(ReverseRequest request) {
        AliPayTradeCancelRequest aliPayTradeCancelRequest = new AliPayTradeCancelRequest();
        aliPayTradeCancelRequest.setAppId(aliPayConfig.getAppId());
        aliPayTradeCancelRequest.setTimestamp(LocalDateTime.now().format(formatter));
        AliPayTradeQueryRequest.BizContent bizContent = new AliPayTradeQueryRequest.BizContent();
        bizContent.setOutTradeNo(request.getOrderId());
        bizContent.setTradeNo(null);
        aliPayTradeCancelRequest.setBizContent(JsonUtil.toJsonWithUnderscores(bizContent).replaceAll("\\s*", ""));
        aliPayTradeCancelRequest.setSign(AliPaySignature.sign(MapUtil.object2MapWithUnderline(aliPayTradeCancelRequest), aliPayConfig.getPrivateKey()));

        Call<AliPayTradeCancelResponse> call = null;
        if (aliPayConfig.isSandbox()) {
            call = devRetrofit.create(AliPayApi.class).reverse((MapUtil.object2MapWithUnderline(aliPayTradeCancelRequest)));
        } else {
            call = retrofit.create(AliPayApi.class).reverse((MapUtil.object2MapWithUnderline(aliPayTradeCancelRequest)));
        }

        Response<AliPayTradeCancelResponse> retrofitResponse = null;
        try {
            retrofitResponse = call.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        assert retrofitResponse != null;
        if (!retrofitResponse.isSuccessful()) {
            throw new RuntimeException("【撤销支付宝订单】alipay.trade.cancel. 网络异常");
        }
        assert retrofitResponse.body() != null;
        AliPayTradeCancelResponse.Content response = retrofitResponse.body().getAlipayTradeCancelResponse();

        /*
        if (!response.getCode().equals(AliPayConstants.RESPONSE_CODE_SUCCESS)) {
            throw new RuntimeException("【撤销支付宝订单】alipay.trade.cancel. code=" + response.getCode() + ", returnMsg=" + response.getMsg() + String.format("|%s|%s", response.getSubCode(), response.getSubMsg()));
        }
         */
        return ReverseResponse.builder()
                .resultCode(response.getCode())
                .errCode(response.getSubCode())
                .errCodeDes(response.getSubMsg())
                .build();
    }

    @Override
    public boolean verify(Map<String, String> toBeVerifiedParamMap, SignType signType, String sign) {
        return AliPaySignature.verify(toBeVerifiedParamMap, aliPayConfig.getAliPayPublicKey());
    }

    /**
     * 异步通知
     *
     * @param notifyData
     * @return
     */
    @Override
    public NotifyResponse asyncNotify(String notifyData) {
        try {
            notifyData = URLDecoder.decode(notifyData, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        //签名校验
        if (!AliPaySignature.verify(MapUtil.form2Map(notifyData), aliPayConfig.getAliPayPublicKey())) {
            log.error("【支付宝支付异步通知】签名验证失败, response={}", notifyData);
            throw new LmbPayException(LmbPayExResultEnum.ASYNC_SIGN_VERIFY_FAIL);//"【支付宝支付异步通知】签名验证失败
        }

        HashMap<String, String> params = MapUtil.form2MapWithCamelCase(notifyData);
        AliPayAsyncResponse response = MapUtil.mapToObject(params, AliPayAsyncResponse.class);
        String tradeStatus = response.getTradeStatus();
        if (!tradeStatus.equals(AliPayTradeStatusEnum.TRADE_FINISHED.name()) && !tradeStatus.equals(AliPayTradeStatusEnum.TRADE_SUCCESS.name())) {
            throw new RuntimeException("【支付宝支付异步通知】发起支付, trade_status != SUCCESS | FINISHED");  // 在支付宝的业务通知中，只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时，支付宝才会认定为买家付款成功。
        }
        return buildNotifyResponse(response);
    }


    private NotifyResponse buildNotifyResponse(AliPayAsyncResponse response) {
        NotifyResponse notifyResponse = new NotifyResponse();
        notifyResponse.setAppId(response.getAppId());
        notifyResponse.setOpenid(response.getBuyerId());
        notifyResponse.setOrderId(response.getOutTradeNo());
        notifyResponse.setOutOrderId(response.getTradeNo());
        notifyResponse.setOrderAmount(response.getTotalAmount());
        notifyResponse.setFinishTime(response.getGmtPayment());
        return notifyResponse;
    }









    @Override
    public PayBankResponse payBank(PayBankRequest request) {
        AliPayBankRequest aliPayBankRequest = new AliPayBankRequest();
        aliPayBankRequest.setAppId(aliPayConfig.getAppId());
        aliPayBankRequest.setTimestamp(LocalDateTime.now().format(formatter));
        AliPayBankRequest.BizContent bizContent = new AliPayBankRequest.BizContent();
        bizContent.setOutBizNo(request.getOrderId());
        bizContent.setProductCode("TRANS_BANKCARD_NO_PWD");
        bizContent.setOrderTitle(request.getDesc());
        bizContent.setRemark(request.getDesc());
        AliPayBankRequest.BizContent.Participant participant = new AliPayBankRequest.BizContent.Participant();
        participant.setIdentity(request.getBankNo());
        participant.setName(request.getTrueName());
        participant.setIdentityType("BANKCARD_ACCOUNT");
        AliPayBankRequest.BizContent.Participant.BankcardExtInfo bankcardExtInfo = new AliPayBankRequest.BizContent.Participant.BankcardExtInfo();
        //暂时先默认对私
        bankcardExtInfo.setAccountType(2);
        bankcardExtInfo.setBankCode(request.getBankCode());
        participant.setBankcardExtInfo(bankcardExtInfo);
        bizContent.setPayeeInfo(participant);
        aliPayBankRequest.setBizContent(JsonUtil.toJsonWithUnderscores(bizContent).replaceAll("\\s*", ""));
        aliPayBankRequest.setSign(AliPaySignature.sign(MapUtil.object2MapWithUnderline(aliPayBankRequest), aliPayConfig.getPrivateKey()));

        Call<AliPayBankResponse> call = retrofit.create(AliPayApi.class).payBank((MapUtil.object2MapWithUnderline(aliPayBankRequest)));

        Response<AliPayBankResponse> retrofitResponse = null;
        try {
            retrofitResponse = call.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        assert retrofitResponse != null;
        if (!retrofitResponse.isSuccessful()) {
            throw new RuntimeException("【支付宝转账到银行卡】网络异常");
        }
        assert retrofitResponse.body() != null;
        AliPayBankResponse.AlipayFundTransUniTransferResponse response = retrofitResponse.body().getAlipayFundTransUniTransferResponse();
        if (!response.getCode().equals(AliPayConstants.RESPONSE_CODE_SUCCESS)) {
            throw new RuntimeException("【支付宝转账到银行卡】code=" + response.getCode() + ", returnMsg=" + response.getMsg());
        }

        return PayBankResponse.builder()
                .orderId(response.getOutBizNo())
                .outOrderId(response.getOrderId())
                .payFundOrderId(response.getPayRundOrderId())
                .status(response.getStatus())
                .build();
    }
}
